#ifndef UTIL_LOG_H
#define UTIL_LOG_H

#include <iostream>
#include <fstream>

namespace util
{
#ifndef _DEBUG
static std::ofstream fstdout;
static std::ofstream fstderr;

struct Log
{
	Log()
	{
		fstdout.open("stdout.txt");
		if (!fstdout)
			std::cerr << "Cannot write stdout.txt" << std::endl;

		fstderr.open("stderr.txt");
		if (!fstderr)
			std::cerr << "Cannot write stderr.txt" << std::endl;
	}
	
	~Log()
	{
		// if nothing has been written to the file, remove it
		if (!fstdout.tellp())
		{
			fstdout.close();
			std::remove("stdout.txt");
		}
		
		// if nothing has been written to the file, remove it
		if (!fstdout.tellp())
		{
			fstderr.close();
			std::remove("stderr.txt");
		}
	}
} LogInstance;
#endif

#ifdef _DEBUG
#ifndef LOG_STDOUT
#define LOG_STDOUT std::cout
#endif
#ifndef LOG_STDERR
#define LOG_STDERR std::cerr
#endif
#else
#ifndef LOG_STDOUT
#define LOG_STDOUT fstdout
#endif
#ifndef LOG_STDERR
#define LOG_STDERR fstderr
#endif
#endif

/// Program can't continue, abort immediately
#define LOG_FATAL(x)    LOG_STDERR << "FATAL ERROR - " << x << std::endl

/// A serious error, user must be informed about it
#define LOG_ERROR(x)    LOG_STDERR << "ERROR - " << x << std::endl

/// User is normally informed about it but may be ignored
#define LOG_WARN(x)     LOG_STDERR << "WARN - " << x << std::endl

/// Normal message (i.e. normal output of a non GUI app)
#define LOG_MSG(x)      LOG_STDOUT << x << std::endl

/// Informational: might go to the status line of GUI app
#define LOG_STATUS(x)   LOG_STDOUT << "STATUS - " << x << std::endl

/// Informational message (a.k.a 'verbose')
#define LOG_INFO(x)     LOG_STDOUT << "INFO - " << x << std::endl

#ifdef _DEBUG
    /// Never shown to the user, disabled in release mode
	#define LOG_DEBUG(x)    LOG_STDOUT << "DEBUG - " << x << std::endl

    /// Trace messages are also only enabled in debug mode
	#define LOG_TRACE(x)    LOG_STDOUT << "TRACE - " << x << std::endl
#else
    /// Never shown to the user, disabled in release mode
	#define LOG_DEBUG(x)

    /// Trace messages are also only enabled in debug mode
	#define LOG_TRACE(x)
#endif

}

#endif // UTIL_LOG_H
